package com.zkq.graduate.controller;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zhuozhengsoft.pageoffice.FileSaver;
import com.zhuozhengsoft.pageoffice.OpenModeType;
import com.zhuozhengsoft.pageoffice.PageOfficeCtrl;
import com.zkq.graduate.enums.ResponseEnum;
import com.zkq.graduate.pojo.*;
import com.zkq.graduate.service.*;
import com.zkq.graduate.util.FileUtil;
import com.zkq.graduate.util.ResultHandler;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author zhangkaiqiang
 * @Date 2019/11/25  11:23
 * @Description TODO
 *
 * 教师控制类
 */
@Slf4j
@Controller
@RequestMapping("/api/v1/teacher")
@Api(tags = {"教师模块接口"},description = "教师模块接口")
public class TeacherController {

	@Resource(name = "titleService")
	private TitleService titleService;


	@Resource(name="selectedTitleService")
	private SelectedTitleService selectedTitleService;

	@Resource(name = "mongoService")
	private MongoDbService mongoService;


	@Resource(name = "fileRecordService")
	private FileRecordService fileRecordService;

	@Resource(name = "majorService")
	private MajorService majorService;

	/**
	 * 得到当前老师发布的所有可选题目
	 * @param request
	 * @return
	 */
	@com.zkq.graduate.annotation.Teacher
	@ResponseBody
	@GetMapping("/titles")
	@ApiOperation(value = "展示教师发布的所有可选题目",notes = "带有分页操作")
	public ResultHandler<Title> listTitleByTeacherId(
											@RequestParam("page") int currentPage,
											@RequestParam("limit") int pageSize,
											HttpServletRequest request){
		String teacherId= (String) request.getAttribute("account");
		PageHelper.startPage(currentPage, pageSize);
		List<Title> titleList=titleService.listTitleByTeacherId(teacherId);
		PageInfo<Title> page = new PageInfo(titleList);
		return ResultHandler.success(page);
	}


	@com.zkq.graduate.annotation.Teacher
	@ResponseBody
	@PostMapping("/title")
	@ApiOperation(value = "新增一条可选题目",notes = "")
	public ResultHandler<String> insertOneTitle(Title title, Major major,HttpServletRequest request){
		Integer teacherId= Integer.valueOf((String) request.getAttribute("account"));
		Teacher teacher=Teacher.builder().teacherId(teacherId).build();
		title.setTeacher(teacher);
		title.setMajor(major);
		if(titleService.insertOneTitle(title)){
			log.info(teacherId+"add a selected project");
			return ResultHandler.success();
		}
		return ResultHandler.fail(ResponseEnum.INSERT_ERROR);
	}


	@com.zkq.graduate.annotation.Teacher
	@ResponseBody
	@DeleteMapping("/titles/{ids}")
	@ApiOperation(value = "删除某些可选题目",notes = "接口提供批量删除与单个删除操作")
	public ResultHandler<String> delTitle(@PathVariable("ids") String ids){
		if(StringUtils.isNotBlank(ids)){
			String[] titleIds=ids.split(",");
			if(titleService.delTitles(titleIds)){
				return ResultHandler.success();
			}
		}
		return ResultHandler.fail(ResponseEnum.DELETE_ERROR);
	}

	@com.zkq.graduate.annotation.Teacher
	@ResponseBody
	@PatchMapping("/title")
	@ApiOperation(value = "编辑某个可选题目",notes = "")
	public ResultHandler<String> editTitle(Title title,Major major){
		title.setMajor(major);
		if(titleService.editTitle(title)){
			return ResultHandler.success();
		}
		return ResultHandler.fail(ResponseEnum.UPDATE_ERROR);
	}


	@ResponseBody
	@GetMapping("/title/{id}")
	@ApiOperation(value = "根据id查看某个可选题目的详情",notes = "")
	public ResultHandler<String> getTitleById(@PathVariable("id") String id){
		if(StringUtils.isNotBlank(id)){
			return ResultHandler.success(titleService.getTitleById(id));
		}
		return ResultHandler.fail(ResponseEnum.SELECT_ERROR);
	}


	@GetMapping("/students")
	@ResponseBody
	@com.zkq.graduate.annotation.Teacher
	@ApiOperation(value = "查看选择某个可选题目的所有学生" ,notes = "带有分页查询")
	public ResultHandler<StudentVo> listAllStudentByTeacher(
									@RequestParam("page") int currentPage,
									@RequestParam("limit") int pageSize,
									String titleId){
		if(StringUtils.isNotBlank(titleId)){
			PageHelper.startPage(currentPage,pageSize);
			List<StudentVo> studentVos=selectedTitleService.listAllStudentByTeacher(titleId);
			PageInfo page=new PageInfo(studentVos);
			return ResultHandler.success(page);
		}
		return null;
	}


	@PatchMapping("/passStudentSelected")
	@ResponseBody
	@com.zkq.graduate.annotation.Teacher
	public ResultHandler<String> passStudentSelected(String id){
		if(StringUtils.isNotBlank(id)){
			String[] ids=id.split(",");
			if(selectedTitleService.teacherPassStudentSelected(ids)){
				return ResultHandler.success();
			}
		}
		return ResultHandler.fail(ResponseEnum.UPDATE_ERROR);
	}

	@PatchMapping("/rejectStudentSelected")
	@ResponseBody
	@com.zkq.graduate.annotation.Teacher
	public ResultHandler<String> rejectStudentSelected(StudentVo studentVo){
		if(selectedTitleService.teacherRejectStudentSelected(studentVo)){
			return ResultHandler.success();
		}
		return ResultHandler.fail(ResponseEnum.UPDATE_ERROR);
	}


	@GetMapping("/OpenAndPaper")
	@ResponseBody
	@com.zkq.graduate.annotation.Teacher
	@ApiOperation(value = "查看学生的开题报告/毕业论文上传记录",notes = "允许学生上传多次,教师只审核最新的文件")
	public ResultHandler<Page> findStudentOpenOrPaper(
			HttpServletRequest request,
			String flag,
			@RequestParam("page") int currentPage,
			@RequestParam("limit") int pageSize){
		Integer teacherId= Integer.valueOf((String) request.getAttribute("account"));
		ResultHandler<Page> page=null;
		List<String> fields=new ArrayList<>();
		fields.add("fileName");
		fields.add("uploadTime");
		fields.add("status");
		fields.add("isLast");
		fields.add("studentId");
		if(StringUtils.isNotBlank(flag)){
			Map<String,Object> map=new HashMap<>(16);
			map.put("title.teacher.teacherId",teacherId);
			map.put("isLast",true);
			page=mongoService.findStudentPaperWithPaging(map,flag,currentPage,pageSize,fields);
		}
		return page;
	}


	@GetMapping("/design/{studentId}/{flag}")
	@com.zkq.graduate.annotation.Teacher
	@com.zkq.graduate.annotation.Student
	@ApiOperation(value = "教师打开文件进行审核/学生查看审核详情")
	public ModelAndView checkOpen(
			HttpServletRequest request,
			Map<String,Object> map,
			@PathVariable("studentId") String studentId,
			@PathVariable("flag") String flag){


		List<String> fields=new ArrayList<>();
		fields.add("fileName");
		fields.add("status");
		fields.add("isLast");
		fields.add("fileContext");
		Optional<StudentWithReport> studentWithReport=mongoService.findLastStudentPaper(studentId,flag,fields);
		studentWithReport.ifPresent((item)->{
			item.setStudentId(studentId);
		});
		String filePath=FileUtil.createOneFile(studentWithReport.get());
		PageOfficeCtrl poCtrl=new PageOfficeCtrl(request);
		// 设置授权程序servlet
		poCtrl.setServerPage("/poserver.zz");
		// 设置文档名称
		poCtrl.setCaption(studentWithReport.map(StudentWithReport::getFileName).orElse(""));
		// 设置保存的action
		poCtrl.setSaveFilePage("/api/v1/teacher/design");
		// 教师可以编辑文档,学生只能查看教师审核后的文档
		List<Role> roleList= (List<Role>) request.getAttribute("role");
		for(Role role:roleList){
			if(Objects.equals("student",role.getRoleName())){
				poCtrl.webOpen("file://"+filePath, OpenModeType.docReadOnly,"张三");
				break;
			}
			if(Objects.equals("teacher",role.getRoleName())){
				poCtrl.webOpen("file://"+filePath, OpenModeType.docAdmin,"张三");
				break;
			}
		}
		map.put("pageoffice",poCtrl.getHtmlCode("PageOfficeCtrl1"));
		ModelAndView mv = new ModelAndView("open_file");
		return mv;
	}


	@PostMapping("/design")
	@com.zkq.graduate.annotation.Teacher
	@ApiOperation(value = "指导教师保存对论文或开题报告的审核",notes = "该方法仅仅把审核保存到本地文件中,后台定时任务讲审核详情同步到MongoDB中")
	public void saveCheck(HttpServletRequest request, HttpServletResponse response){
		FileSaver fs = new FileSaver(request, response);
		String[] fileNames=fs.getFileName().split("\\\\");
		String fileName=fileNames[fileNames.length-1];
		String studentId=fileName.split("-")[0];
		String fileType=FileUtil.fileType(fileName)==1?"open":"paper";

		// 更新文件状态为审核中
		Map<String,Object> updateCondition=new HashMap<>();
		updateCondition.put("fileName",fileName);
		List<String> fields=new ArrayList<>();
		fields.add("status");
		String status=mongoService.findLastStudentPaper(studentId,fileType,fields).map(item->item.getStatus()).orElse("");
		if(!Objects.equals("审核中",status)){
			StudentWithReport student=StudentWithReport
					.builder()
					.status("审核中")
					.isLast(true)
					.build();
			mongoService.updateFileByAddition(updateCondition,student,fileType);
		}
		fs.saveToFile(fs.getFileName());
		fs.close();
	}


	@ResponseBody
	@GetMapping("/designs")
	@com.zkq.graduate.annotation.Teacher
	@ApiOperation(value = "读取学生提交毕业设计的记录",notes = "允许学生多次上传毕业设计,教师只审核最后上传的毕业设计")
	public ResultHandler<StudentWithReport> findStudentDesignRecord(
			HttpServletRequest request,
			@RequestParam("page") int currentPage,
			@RequestParam("limit") int pageSize){
		 String teacherId= (String) request.getAttribute("account");
		if(StringUtils.isNotBlank(teacherId)){
			PageHelper.startPage(currentPage,pageSize);
			List<StudentWithReport> list=fileRecordService.findRecordByteacherId(teacherId);
			PageInfo<StudentWithReport> page=new PageInfo<>(list);
			return ResultHandler.success(page);
		}
		return ResultHandler.fail(ResponseEnum.SELECT_ERROR);
	}


	@GetMapping("/design/{studentId}")
	@com.zkq.graduate.annotation.Teacher
	@ApiOperation(value = "教师下载学生的毕业设计,进行毕业设计的审核",notes = "")
	public void downloadStudentDesign(@PathVariable("studentId") String studentId,HttpServletResponse response){

		response.setHeader("content-type", "application/octet-stream");
		response.setContentType("application/octet-stream");

		// 待下载的文件
		List<StudentWithReport> list=fileRecordService.findByStudentId(studentId);
		list=list.stream().filter(StudentWithReport::isLast).collect(Collectors.toList());
		String fileName=list.get(0).getFileName();
		// 下载文件能正常显示中文
		try {
			response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
			if(list.size()>0){
				byte[] bytes=new byte[1024];
				File file=new File(list.get(0).getFilePath());
				InputStream in=new FileInputStream(file);
				OutputStream out= response.getOutputStream();
				BufferedOutputStream buffer=new BufferedOutputStream(out);
				while(in.read(bytes)!=-1){
					buffer.write(bytes);
				}
				in.close();
				out.close();
				buffer.close();
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		// 更新状态为已审核
		fileRecordService.updateLast(list.get(0));
	}
}
